/**
 *  A dialog to create or modify ItemClasses
 *   zulianp@lu.unisi.ch & lemmar@lu.unisi.ch
 */


package ch.unisi.inf.projects.java.uom.gui.itemclasseditor;

import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTextField;

import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JLabel;
import javax.swing.Box;

import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import ch.unisi.inf.projects.java.uom.gui.UOMImages;
import ch.unisi.inf.projects.java.uom.gui.commands.IconedCommand;
import ch.unisi.inf.projects.java.uom.elements.*;
import ch.unisi.inf.projects.java.uom.*;
import ch.unisi.inf.projects.java.uom.exceptions.*;
import ch.unisi.inf.projects.java.uom.gui.NameController;
import ch.unisi.inf.projects.java.uom.gui.UOMMainFrame;
import ch.unisi.inf.projects.java.uom.gui.UOMMessagePane;

public final class UOMItemClassEditorDialog extends JDialog
{
    /** We are not going to serialize this class atm */
    private static final long serialVersionUID = -1L;
    
    
    private JPanel panel;
    private final JPanel fieldPanel;
    private JPanel categoryPanel;
    private final ItemClass itemClass;
    private JTextField classNameField;
    private ArrayList<UOMTripleEntryEmbeeder> panelList;
    
    
    public UOMItemClassEditorDialog(final String title, final ItemClass itemClass)
    {
    	super();
        this.setTitle(title);
        this.setLayout(new BorderLayout());
        fieldPanel = new JPanel();
        panelList = new ArrayList<UOMTripleEntryEmbeeder>();
        this.itemClass = itemClass;
        setResizable(false);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		this.addWindowListener(new WindowAdapter() {
			public void windowClosed (final WindowEvent ev) { UOMMainFrame.instance().setEnabled(true); }
		});
		UOMMainFrame.instance().setEnabled(false);
        makeDialog();
        this.setLocationRelativeTo(null);
        setVisible(true);
    }
    
    private void makeDialog()
    {
        //button panel set-up
        panel = new JPanel();
        panel.setLayout(new FlowLayout());
        final JButton addFieldButton = new JButton(new IconedCommand("", "Add a new Field", UOMImages.ADD.getFileName()) {
        	private static final long serialVersionUID = -1L;
        	public final void actionPerformed(final ActionEvent ev) {
        		addActionField();
        	}
        });
        panel.add(addFieldButton);
        final JButton saveClassButton = new JButton(new IconedCommand ("", "Saves this category", UOMImages.SAVE.getFileName()) {
        	private static final long serialVersionUID = -1L;
            public final void actionPerformed(final ActionEvent ev) {
            	saveClass();
            }
        });
        panel.add(Box.createHorizontalStrut(10));
        panel.add(saveClassButton);

        final JButton exitButton = new JButton(new IconedCommand("", "Cancel", UOMImages.CANCEL.getFileName()) {
        	private static final long serialVersionUID = -1L;
        	public final void actionPerformed (final ActionEvent ev) {
        		dispose();
        	}
        });
        panel.add(Box.createHorizontalStrut(10));
        panel.add(exitButton);
        this.add(panel, BorderLayout.SOUTH);
        
        //field panel set-up   
        fieldPanel.setLayout(new GridLayout(0,4));
        this.add(fieldPanel,FlowLayout.CENTER);
        
        JLabel addFieldLabel = new JLabel(" Field name");
        fieldPanel.add(addFieldLabel);
        JLabel chooseTypeLabel = new JLabel(" Field type");
        fieldPanel.add(chooseTypeLabel);
        JLabel listLabel = new JLabel("");
        fieldPanel.add(listLabel);
        JLabel deleteLabel = new JLabel("");
        fieldPanel.add(deleteLabel);
        if (itemClass == null)
        	addActionField();
        else {
        	final Parser parser = Parser.instance();
        	final Set<String> fields = itemClass.getFields().keySet();
        	for (final String field : fields)
        		try {
        			if (!ConstantArrays.ITEM_COMMON_FIELDS.contains(field) && !field.toUpperCase().equals(Constants.ITEM_PRIMARY_KEY.value()))
        				addActionField(parser.dbGetVarName(field), parser.dbGetVarType(field), parser.dbColumnTypeIsList(field));
        		}
        		catch (final UOMException uomex)
        		{
        			uomex.printStackTrace();
        			assert false;
        		}
        }
        
        //category panel set-up
        categoryPanel = new JPanel();
        categoryPanel.setLayout(new GridLayout(0,4));
        this.add(categoryPanel,BorderLayout.NORTH);
        
        if (itemClass == null)
        	classNameField = new JTextField("type new category name");
        else {
        	classNameField = new JTextField(itemClass.getName());
        	classNameField.setEditable(false);
        }
        classNameField.addFocusListener(new FocusListener() {
        	public void focusGained (final FocusEvent ev) {
        		classNameField.setSelectionStart(0);
        		classNameField.setSelectionEnd(classNameField.getText().length());
        	}
        	public void focusLost (final FocusEvent ev) { return; }
        });
        final JLabel classNameFieldLabel = new JLabel("Category name");
        categoryPanel.add(classNameFieldLabel);
        categoryPanel.add(classNameField);
        
        //...
        pack();
        
    }
    
    private void addActionField()
    {
    	addActionField("Type field name", null, false);
    }
    
    
    private void addActionField(final String name, final String type, boolean isList)
    {
    	final UOMTripleEntryEmbeeder embeeder = new UOMTripleEntryEmbeeder(name, type, isList);
    	embeeder.embeedIn(this, panelList);
    	pack();
    	
    }
    

    private void saveClass()
    {
    	boolean isNewItemClassInstance = (itemClass == null);
        final ItemManager manager = ItemManager.instance();
        final String name = classNameField.getText();
        NameController controller = NameController.instance();
        if(!controller.validItemClassName(name) && isNewItemClassInstance) {
        		new UOMMessagePane(controller.getLastControlMessage(), this);
        		return;
        }
        	
        
        
        final HashMap<String,String> fields = new HashMap<String,String>();
        final HashSet<String> fieldNames = new HashSet<String>();
        for(final UOMTripleEntryEmbeeder e : panelList){
        	TripleEntryModel entry = e.getEntry();
            String field = entry.toString();
            fields.put(field.toUpperCase(), null);
            String fieldName = entry.getName();
            fieldNames.add(fieldName);
            
        }
        
        if(!controller.validFieldNames(fieldNames)) { 
        	new UOMMessagePane(controller.getLastControlMessage(), this );
        	return;
        }
        
        
        try {
        	final ItemClass itemClass;
        	if (this.itemClass == null)
        		itemClass = manager.itemClassAdd(name);
        	else
        		itemClass = manager.itemClassGet(name);
            
        	if(!isNewItemClassInstance){
        	 manager.elementSetFields(itemClass, fields);
             manager.elementSave(itemClass);}
            
             if(isNewItemClassInstance){
            	for(final String s : ConstantArrays.ITEM_COMMON_FIELDS.value())
            	{
            		 fields.put(s,null);
            	}

            	manager.elementSetFields(itemClass, fields);
                manager.elementSave(itemClass);
             }
        }
        catch(final Exception ex)
        {
        	ex.printStackTrace();
        	assert false;
        }
		UOMMainFrame.instance().setEnabled(true);
        dispose();
    }
    
    
	public JPanel getFieldPanel() {
		return fieldPanel;
	}

}
